package com.flynn.rock.jwt;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.flynn.rock.exception.JwtAuthenticationException;
import com.flynn.rock.model.dto.system.UserAccountDto;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.HashMap;

@Component
public class HutoolJwtProcessor implements JwtProcessor {

    @Override
    public String createJwtToken(Authentication authentication) {
        if (authentication.getPrincipal() instanceof UserAccountDto userDetails) {
            JwtPayloadMap jwtPayloadMap = new JwtPayloadMap()
                    .putUserId(userDetails.getUser().getUserId())
                    .putDeptId(userDetails.getUser().getDeptId())
                    .putAccount(userDetails.getAccount())
                    .putDefaultExpireTime();
            return JWTUtil.createToken(jwtPayloadMap, "key".getBytes());
        }
        throw new JwtAuthenticationException("用户凭证信息异常");
    }

    @Override
    public String validateJwtToken(String token) {
        // 验签
        boolean verify = JWTUtil.verify(token, "key".getBytes());
        if (!verify) {
            throw new JwtAuthenticationException("非法令牌");
        }
        // 过期
        final JWT jwt = JWTUtil.parseToken(token);
//        if (System.currentTimeMillis() > this.obtainExpireTime(jwt)) {
//            throw new JwtAuthenticationException("令牌已失效");
//        }
        return this.obtainAccount(jwt);
    }

    private Long obtainExpireTime(JWT jwt) {
        return jwt.getPayloads().get("expireTime", Long.class);
    }

    private String obtainAccount(JWT jwt) {
        return jwt.getPayloads().get("account", String.class);
    }

    static class JwtPayloadMap extends HashMap<String, Object> {

        public JwtPayloadMap putUserId(Long userId) {
            this.put("userId", userId);
            return this;
        }

        public JwtPayloadMap putDeptId(Long deptId) {
            this.put("deptId", deptId);
            return this;
        }

        public JwtPayloadMap putAccount(String account) {
            this.put("account", account);
            return this;
        }

        public JwtPayloadMap putDefaultExpireTime() {
            this.put("expireTime", System.currentTimeMillis() + 1000 * 60 * 60);
            return this;
        }
    }
}

